import static org.junit.Assert.*;

import java.util.Arrays;

import org.junit.Test;


public class SetTest {
	Set set = new Set();
	
	public void tearDown() {
		set = new Set(); // To create a new instance of Set for each test
	}

	@Test
	public void testInsert1() {
		
		int nr = 0;
		for(int i = -5; i<= 10; i++){
			set.insert(i);
			nr++;
		}
		
		
		
		// Should test adding in different order as well. 
		//Statement coverage
		set.insert(-3); // inserting something that already exists
		assertFalse(set.toArray().length == 17); // not added
		assertTrue(set.toArray().length == nr); // nr = 16 after the loop
		int expected[] = {-5,-4,-3,-2,-1,0,1,2,3,4,5,6,7,8,9,10};
		
		int ans[] = set.toArray();

		//failed before something is wrong with the method. Fixed bug
		//, from break to return;
		assertTrue(Arrays.equals(expected,ans)); 

	}
	
	@Test
	public void testInsert2(){
		//For additional Branch coverage
		for(int i = -5; i<= 10; i++)
			set.insert(i);

		// This added ensures the additional branch coverage
		
		set.insert(-6); // inserting a new lower number
		assertTrue(set.toArray().length == 17);
		
		int expected2[] = {-6,-5,-4,-3,-2,-1,0,1,2,3,4,5,6,7,8,9,10};
		
		assertTrue(Arrays.equals(set.toArray(), expected2 ));
	
	}
	
	@Test
	public void testInsert3(){
		
		// Test adding in "wrong" order for additional branch cover
		
		set.insert(1);
		set.insert(0);
		int[] expected2 = { 0, 1 };
		int[] actual2 = set.toArray();
		assertTrue(Arrays.equals(expected2, actual2));
		
	}

	@Test
	public void testMember() {

		//setup with insert to array {-1,0,1,2,3,4}

		for(int i = -1; i<= 4; i++){
			set.insert(i);
			
		}
		assertTrue(set.toArray().length == 6); // just to check so 6 values
		
		for(int i = -1; i<= 4; i++)
			assertTrue(set.member(i)); //present in the array, should pass

		// These three methods ensures statement and branch coverage since
		// they cover boundaries: lower values than in the array, values in the
		// array and finally higher values than in the array.
	}
	
	@Test
	public void testMember2(){
		
		for(int i = -1; i<= 4; i++)
			set.insert(i);

		for(int i = 5; i <=10; i++)
			assertFalse(set.member(i)); //not present in the array (higher) value)
			//, should not change
	}
	
	@Test
	public void testMember3(){
		
		for(int i = -1; i<= 4; i++)
			set.insert(i);
		
		for(int i = -6; i>=-2; i++) 
			assertFalse(set.member(i)); //not present in the array (lower value)
			//, should not be added
	}
	
	@Test
	public void testMember4(){
		
		//Test with empty Set, should return false
		assertFalse(set.member(1));
		
	}
	
	@Test
	public void testSection() {
		
		Set set1 = new Set();
		Set set2 = new Set();
		// setup with insert to array set1 {-1,0,1,3,5,7}
		int nr = 0;

		set1.insert(-1);
		set1.insert(0);
		set1.insert(1);
		set1.insert(3); 
		set1.insert(5);
		set1.insert(7);

		assertTrue(set1.toArray().length == 6);

		// setup with insert to array set2 {-2,-1,1,2,3,7}
		set2.insert(-2);
		set2.insert(-1);
		set2.insert(1);
		set2.insert(2);
		set2.insert(3);
		set2.insert(7);

		assertTrue(set2.toArray().length == 6);
		set1.section(set2); //removes one to few, fixed by removing the increase
		// of i in after the remove.

		//System.out.println(set1.toArray().length);

		int[] expected = { 0, 5 };

		int[] actual = set1.toArray();

		assertTrue(set1.toArray().length == 2);
		assertTrue(Arrays.equals(expected, actual));
		
		// This Test suit {-2,-1,1,2,3,7} covers SC and BC

	}
	
	@Test
	public void testSection2(){
		
		
		Set set3 = new Set(); // {1,3,7}
		Set set4 = new Set(); // {}

		set3.insert(1);
		set3.insert(3);
		set3.insert(7);

		int expected[] = { 1, 3, 7 };

		set3.section(set4); // Nothing to delete, should stay the same
		int[] actual = set3.toArray();

		assertTrue(Arrays.equals(expected, actual));
		
		set4.section(set3); // Delete {1,3,7} from nothing, should still be {}
		
		int[] expected2 = {};
		int[] actual2 = set4.toArray();
		
		assertTrue(Arrays.equals(expected2, actual2));

	}
	
	
	@Test
	public void testContainsArithTriple() {
		
		//Test first so it doesn't accept anything with a length < 3 values
		 
		for(int i = 1; i < 3; i++){ // Check with length <3
			set.insert(i);
			assertFalse(set.containsArithTriple()); 
		}
		assertTrue(set.toArray().length == 2);
		
		// The method was wrong before since it accepted the same indexes 
		// i and j in the method. fixed by adding a check if i!=j. This could
		// also be fixed by changing the second for loop from j <= i to j < i.

		set.insert(3); // Test values 1,2,3. Should be ok, 2-1 = 3-2
		assertTrue(set.containsArithTriple());
	}
	
	@Test
	public void testContainsArithTriple2(){

		assertFalse(set.containsArithTriple()); // Check empty Set.

	}
	
	@Test
	public void testContainsArithTriple3(){
		
		//Test 2
		
		set.insert(-5);
		set.insert(0);
		set.insert(5);
		// Test values -5, 0, 5. Should be ok, 0-(-5) = 5 - 0
		assertTrue(set.containsArithTriple());
	}
	
	@Test
	public void testContainsArithTriple4(){
		
		 // test with values not beside each other
		// {-5,0,1,2,5}
		set.insert(-5);
		set.insert(1);
		set.insert(2);
		set.insert(0);
		set.insert(5);

		assertTrue(set.containsArithTriple());
	}
	
	@Test
	public void testContainsArithTriple5(){
		
		//Test with a value that should not pass {-2,1,5}
		
		set.insert(-2);
		set.insert(1);
		set.insert(5);

		assertFalse(set.containsArithTriple());
	}

}
